<template>
  <div class="voice-input-component">
    <!-- 语音输入主界面 -->
    <div class="voice-input-container">
      <!-- 录音状态显示 -->
      <div class="recording-status" :class="{ active: isRecording, processing: isProcessing }">
        <div class="status-indicator">
          <div class="pulse-ring" v-if="isRecording"></div>
          <div class="status-icon">
            <i v-if="!isRecording && !isProcessing" class="fas fa-microphone"></i>
            <i v-else-if="isRecording" class="fas fa-stop"></i>
            <i v-else-if="isProcessing" class="fas fa-spinner fa-spin"></i>
          </div>
        </div>
        
        <div class="status-text">
          <h3 v-if="!isRecording && !isProcessing">点击开始录音</h3>
          <h3 v-else-if="isRecording">正在录音中...</h3>
          <h3 v-else-if="isProcessing">正在识别语音...</h3>
          
          <p v-if="isRecording" class="recording-time">
            {{ formatTime(recordingTime) }}
          </p>
          <p v-else-if="!isProcessing" class="instruction">
            请清晰地描述您的症状
          </p>
        </div>
      </div>

      <!-- 音频波形可视化 -->
      <div class="audio-visualizer" v-if="isRecording || audioData.length > 0">
        <canvas 
          ref="visualizerCanvas" 
          :width="canvasWidth" 
          :height="canvasHeight"
          class="visualizer-canvas"
        ></canvas>
      </div>

      <!-- 控制按钮 -->
      <div class="control-buttons">
        <el-button 
          @click="toggleRecording"
          :type="isRecording ? 'danger' : 'primary'"
          :size="'large'"
          :disabled="isProcessing"
          class="record-btn"
        >
          <i :class="isRecording ? 'fas fa-stop' : 'fas fa-microphone'"></i>
          {{ isRecording ? '停止录音' : '开始录音' }}
        </el-button>
        
        <el-button 
          v-if="audioBlob"
          @click="playRecording"
          type="success"
          size="large"
          :disabled="isRecording || isProcessing"
          class="play-btn"
        >
          <i :class="isPlaying ? 'fas fa-pause' : 'fas fa-play'"></i>
          {{ isPlaying ? '暂停播放' : '播放录音' }}
        </el-button>
        
        <el-button 
          v-if="audioBlob"
          @click="clearRecording"
          type="warning"
          size="large"
          :disabled="isRecording || isProcessing"
          class="clear-btn"
        >
          <i class="fas fa-trash"></i>
          清除录音
        </el-button>
      </div>

      <!-- 识别结果显示 -->
      <div class="recognition-result" v-if="recognitionText || isProcessing">
        <div class="result-header">
          <h4>
            <i class="fas fa-comment-alt"></i>
            语音识别结果
          </h4>
          <div class="result-actions" v-if="recognitionText">
            <el-button 
              @click="copyToClipboard"
              type="text"
              size="small"
            >
              <i class="fas fa-copy"></i>
              复制
            </el-button>
            <el-button 
              @click="insertToInput"
              type="text"
              size="small"
            >
              <i class="fas fa-plus"></i>
              插入
            </el-button>
          </div>
        </div>
        
        <div class="result-content">
          <div v-if="isProcessing" class="processing-indicator">
            <el-skeleton :rows="3" animated />
            <p class="processing-text">正在识别语音内容，请稍候...</p>
          </div>
          
          <div v-else-if="recognitionText" class="recognition-text">
            <p>{{ recognitionText }}</p>
            
            <!-- 置信度显示 -->
            <div class="confidence-indicator" v-if="recognitionConfidence">
              <span class="confidence-label">识别置信度：</span>
              <el-progress 
                :percentage="Math.round(recognitionConfidence * 100)"
                :color="getConfidenceColor(recognitionConfidence)"
                :show-text="true"
                :stroke-width="6"
                class="confidence-bar"
              />
            </div>
          </div>
          
          <div v-else-if="recognitionError" class="error-message">
            <i class="fas fa-exclamation-triangle"></i>
            <p>{{ recognitionError }}</p>
            <el-button @click="retryRecognition" type="primary" size="small">
              重试识别
            </el-button>
          </div>
        </div>
      </div>

      <!-- 语音设置 -->
      <div class="voice-settings">
        <el-collapse v-model="settingsExpanded">
          <el-collapse-item title="语音设置" name="settings">
            <div class="settings-content">
              <!-- 语言选择 -->
              <div class="setting-item">
                <label class="setting-label">识别语言：</label>
                <el-select v-model="selectedLanguage" size="small" style="width: 150px">
                  <el-option 
                    v-for="lang in supportedLanguages" 
                    :key="lang.code"
                    :label="lang.name"
                    :value="lang.code"
                  />
                </el-select>
              </div>
              
              <!-- 音频质量 -->
              <div class="setting-item">
                <label class="setting-label">音频质量：</label>
                <el-select v-model="audioQuality" size="small" style="width: 120px">
                  <el-option label="标准" value="standard" />
                  <el-option label="高质量" value="high" />
                </el-select>
              </div>
              
              <!-- 自动停止 -->
              <div class="setting-item">
                <label class="setting-label">自动停止：</label>
                <el-switch 
                  v-model="autoStop"
                  active-text="开启"
                  inactive-text="关闭"
                />
              </div>
              
              <!-- 最大录音时长 -->
              <div class="setting-item" v-if="autoStop">
                <label class="setting-label">最大时长：</label>
                <el-input-number 
                  v-model="maxRecordingTime"
                  :min="10"
                  :max="300"
                  :step="10"
                  size="small"
                  style="width: 120px"
                />
                <span class="unit-text">秒</span>
              </div>
            </div>
          </el-collapse-item>
        </el-collapse>
      </div>

      <!-- 历史记录 -->
      <div class="voice-history" v-if="voiceHistory.length > 0">
        <div class="history-header">
          <h4>
            <i class="fas fa-history"></i>
            语音记录
          </h4>
          <el-button 
            @click="clearHistory"
            type="text"
            size="small"
            class="clear-history-btn"
          >
            <i class="fas fa-trash"></i>
            清空记录
          </el-button>
        </div>
        
        <div class="history-list">
          <div 
            v-for="(record, index) in voiceHistory" 
            :key="index"
            class="history-item"
          >
            <div class="history-content">
              <div class="history-text">{{ record.text }}</div>
              <div class="history-meta">
                <span class="history-time">{{ formatDateTime(record.timestamp) }}</span>
                <span class="history-duration">{{ formatTime(record.duration) }}</span>
              </div>
            </div>
            
            <div class="history-actions">
              <el-button 
                @click="playHistoryRecord(record)"
                type="text"
                size="small"
              >
                <i class="fas fa-play"></i>
              </el-button>
              <el-button 
                @click="useHistoryText(record.text)"
                type="text"
                size="small"
              >
                <i class="fas fa-plus"></i>
              </el-button>
              <el-button 
                @click="deleteHistoryRecord(index)"
                type="text"
                size="small"
                class="delete-btn"
              >
                <i class="fas fa-trash"></i>
              </el-button>
            </div>
          </div>
        </div>
      </div>
    </div>
  </div>
</template>

<script setup>
import { ref, computed, watch, onMounted, onUnmounted, nextTick } from 'vue'
import { ElButton, ElSelect, ElOption, ElSwitch, ElInputNumber, ElCollapse, ElCollapseItem, ElProgress, ElSkeleton, ElMessage, ElMessageBox } from 'element-plus'

// Props
const props = defineProps({
  modelValue: {
    type: String,
    default: ''
  },
  placeholder: {
    type: String,
    default: '请描述您的症状...'
  },
  maxLength: {
    type: Number,
    default: 1000
  },
  autoInsert: {
    type: Boolean,
    default: true
  }
})

// Emits
const emit = defineEmits(['update:modelValue', 'voice-result', 'recording-start', 'recording-stop'])

// 响应式数据
const isRecording = ref(false)
const isProcessing = ref(false)
const isPlaying = ref(false)
const recordingTime = ref(0)
const recognitionText = ref('')
const recognitionConfidence = ref(0)
const recognitionError = ref('')
const audioBlob = ref(null)
const audioData = ref([])
const settingsExpanded = ref([])
const voiceHistory = ref([])

// 设置选项
const selectedLanguage = ref('zh-CN')
const audioQuality = ref('standard')
const autoStop = ref(true)
const maxRecordingTime = ref(60)

// 支持的语言
const supportedLanguages = ref([
  { code: 'zh-CN', name: '中文(普通话)' },
  { code: 'zh-TW', name: '中文(繁体)' },
  { code: 'en-US', name: 'English (US)' },
  { code: 'en-GB', name: 'English (UK)' },
  { code: 'ja-JP', name: '日本語' },
  { code: 'ko-KR', name: '한국어' }
])

// 音频相关
let mediaRecorder = null
let audioContext = null
let analyser = null
let microphone = null
let recordingTimer = null
let audioChunks = []

// Canvas 相关
const visualizerCanvas = ref(null)
const canvasWidth = ref(400)
const canvasHeight = ref(100)

// 计算属性
const canUseVoiceInput = computed(() => {
  return 'webkitSpeechRecognition' in window || 'SpeechRecognition' in window
})

// 方法
const initializeAudio = async () => {
  try {
    const stream = await navigator.mediaDevices.getUserMedia({ 
      audio: {
        echoCancellation: true,
        noiseSuppression: true,
        sampleRate: audioQuality.value === 'high' ? 48000 : 44100
      } 
    })
    
    // 创建音频上下文
    audioContext = new (window.AudioContext || window.webkitAudioContext)()
    analyser = audioContext.createAnalyser()
    microphone = audioContext.createMediaStreamSource(stream)
    
    analyser.fftSize = 256
    microphone.connect(analyser)
    
    // 创建媒体录制器
    mediaRecorder = new MediaRecorder(stream, {
      mimeType: 'audio/webm;codecs=opus'
    })
    
    mediaRecorder.ondataavailable = (event) => {
      if (event.data.size > 0) {
        audioChunks.push(event.data)
      }
    }
    
    mediaRecorder.onstop = () => {
      audioBlob.value = new Blob(audioChunks, { type: 'audio/webm' })
      audioChunks = []
      processAudioRecognition()
    }
    
    return true
  } catch (error) {
    console.error('Failed to initialize audio:', error)
    ElMessage.error('无法访问麦克风，请检查权限设置')
    return false
  }
}

const toggleRecording = async () => {
  if (!isRecording.value) {
    await startRecording()
  } else {
    stopRecording()
  }
}

const startRecording = async () => {
  if (!canUseVoiceInput.value) {
    ElMessage.error('您的浏览器不支持语音识别功能')
    return
  }
  
  const initialized = await initializeAudio()
  if (!initialized) return
  
  try {
    isRecording.value = true
    recordingTime.value = 0
    recognitionText.value = ''
    recognitionError.value = ''
    
    mediaRecorder.start()
    startVisualization()
    
    // 开始计时
    recordingTimer = setInterval(() => {
      recordingTime.value++
      
      // 自动停止
      if (autoStop.value && recordingTime.value >= maxRecordingTime.value) {
        stopRecording()
      }
    }, 1000)
    
    emit('recording-start')
    ElMessage.success('开始录音')
  } catch (error) {
    console.error('Failed to start recording:', error)
    ElMessage.error('录音启动失败')
    isRecording.value = false
  }
}

const stopRecording = () => {
  if (!isRecording.value) return
  
  isRecording.value = false
  
  if (recordingTimer) {
    clearInterval(recordingTimer)
    recordingTimer = null
  }
  
  if (mediaRecorder && mediaRecorder.state === 'recording') {
    mediaRecorder.stop()
  }
  
  stopVisualization()
  emit('recording-stop', recordingTime.value)
  ElMessage.success('录音已停止')
}

const startVisualization = () => {
  if (!analyser || !visualizerCanvas.value) return
  
  const canvas = visualizerCanvas.value
  const ctx = canvas.getContext('2d')
  const bufferLength = analyser.frequencyBinCount
  const dataArray = new Uint8Array(bufferLength)
  
  const draw = () => {
    if (!isRecording.value) return
    
    requestAnimationFrame(draw)
    
    analyser.getByteFrequencyData(dataArray)
    
    ctx.fillStyle = '#f0f0f0'
    ctx.fillRect(0, 0, canvas.width, canvas.height)
    
    const barWidth = (canvas.width / bufferLength) * 2.5
    let barHeight
    let x = 0
    
    for (let i = 0; i < bufferLength; i++) {
      barHeight = (dataArray[i] / 255) * canvas.height * 0.8
      
      const gradient = ctx.createLinearGradient(0, canvas.height - barHeight, 0, canvas.height)
      gradient.addColorStop(0, '#2c5aa0')
      gradient.addColorStop(1, '#1890ff')
      
      ctx.fillStyle = gradient
      ctx.fillRect(x, canvas.height - barHeight, barWidth, barHeight)
      
      x += barWidth + 1
    }
  }
  
  draw()
}

const stopVisualization = () => {
  if (visualizerCanvas.value) {
    const ctx = visualizerCanvas.value.getContext('2d')
    ctx.clearRect(0, 0, canvasWidth.value, canvasHeight.value)
  }
}

const processAudioRecognition = async () => {
  if (!audioBlob.value) return
  
  isProcessing.value = true
  recognitionError.value = ''
  
  try {
    // 模拟语音识别 API 调用
    // 在实际应用中，这里应该调用真实的语音识别服务
    await simulateVoiceRecognition()
  } catch (error) {
    console.error('Voice recognition failed:', error)
    recognitionError.value = '语音识别失败，请重试'
  } finally {
    isProcessing.value = false
  }
}

const simulateVoiceRecognition = async () => {
  // 模拟 API 延迟
  await new Promise(resolve => setTimeout(resolve, 2000))
  
  // 模拟识别结果
  const sampleTexts = [
    '我最近感到头痛，特别是在太阳穴附近，疼痛程度大约是6分',
    '胸部有些闷痛，呼吸时会加重，已经持续了两天',
    '腹部右下方疼痛，按压时疼痛加剧，伴有轻微发热',
    '膝盖关节疼痛，上下楼梯时明显，早晨起床后僵硬',
    '喉咙痛，吞咽困难，声音嘶哑，已经三天了'
  ]
  
  const randomText = sampleTexts[Math.floor(Math.random() * sampleTexts.length)]
  const confidence = 0.85 + Math.random() * 0.1 // 85-95% 置信度
  
  recognitionText.value = randomText
  recognitionConfidence.value = confidence
  
  // 添加到历史记录
  addToHistory(randomText, recordingTime.value)
  
  // 触发事件
  emit('voice-result', {
    text: randomText,
    confidence: confidence,
    duration: recordingTime.value
  })
  
  // 自动插入到输入框
  if (props.autoInsert) {
    insertToInput()
  }
}

const retryRecognition = () => {
  if (audioBlob.value) {
    processAudioRecognition()
  }
}

const playRecording = () => {
  if (!audioBlob.value) return
  
  if (isPlaying.value) {
    // 暂停播放
    isPlaying.value = false
    return
  }
  
  const audio = new Audio(URL.createObjectURL(audioBlob.value))
  
  audio.onplay = () => {
    isPlaying.value = true
  }
  
  audio.onended = () => {
    isPlaying.value = false
  }
  
  audio.onerror = () => {
    isPlaying.value = false
    ElMessage.error('播放失败')
  }
  
  audio.play()
}

const clearRecording = async () => {
  try {
    await ElMessageBox.confirm(
      '确定要清除当前录音吗？',
      '确认清除',
      {
        confirmButtonText: '确定',
        cancelButtonText: '取消',
        type: 'warning'
      }
    )
    
    audioBlob.value = null
    recognitionText.value = ''
    recognitionConfidence.value = 0
    recognitionError.value = ''
    recordingTime.value = 0
    
    ElMessage.success('录音已清除')
  } catch {
    // 用户取消
  }
}

const copyToClipboard = async () => {
  try {
    await navigator.clipboard.writeText(recognitionText.value)
    ElMessage.success('已复制到剪贴板')
  } catch (error) {
    ElMessage.error('复制失败')
  }
}

const insertToInput = () => {
  if (!recognitionText.value) return
  
  const currentValue = props.modelValue || ''
  const newValue = currentValue ? `${currentValue} ${recognitionText.value}` : recognitionText.value
  
  emit('update:modelValue', newValue)
  ElMessage.success('已插入到输入框')
}

const addToHistory = (text, duration) => {
  const record = {
    text,
    duration,
    timestamp: new Date(),
    audioBlob: audioBlob.value
  }
  
  voiceHistory.value.unshift(record)
  
  // 限制历史记录数量
  if (voiceHistory.value.length > 10) {
    voiceHistory.value = voiceHistory.value.slice(0, 10)
  }
  
  // 保存到本地存储
  saveHistoryToStorage()
}

const clearHistory = async () => {
  try {
    await ElMessageBox.confirm(
      '确定要清空所有语音记录吗？',
      '确认清空',
      {
        confirmButtonText: '确定',
        cancelButtonText: '取消',
        type: 'warning'
      }
    )
    
    voiceHistory.value = []
    localStorage.removeItem('voiceHistory')
    ElMessage.success('历史记录已清空')
  } catch {
    // 用户取消
  }
}

const playHistoryRecord = (record) => {
  if (record.audioBlob) {
    const audio = new Audio(URL.createObjectURL(record.audioBlob))
    audio.play()
  }
}

const useHistoryText = (text) => {
  const currentValue = props.modelValue || ''
  const newValue = currentValue ? `${currentValue} ${text}` : text
  
  emit('update:modelValue', newValue)
  ElMessage.success('已插入历史记录文本')
}

const deleteHistoryRecord = (index) => {
  voiceHistory.value.splice(index, 1)
  saveHistoryToStorage()
}

const saveHistoryToStorage = () => {
  try {
    const historyData = voiceHistory.value.map(record => ({
      text: record.text,
      duration: record.duration,
      timestamp: record.timestamp.toISOString()
    }))
    localStorage.setItem('voiceHistory', JSON.stringify(historyData))
  } catch (error) {
    console.error('Failed to save history:', error)
  }
}

const loadHistoryFromStorage = () => {
  try {
    const saved = localStorage.getItem('voiceHistory')
    if (saved) {
      const historyData = JSON.parse(saved)
      voiceHistory.value = historyData.map(record => ({
        ...record,
        timestamp: new Date(record.timestamp),
        audioBlob: null // 音频数据不保存到本地存储
      }))
    }
  } catch (error) {
    console.error('Failed to load history:', error)
  }
}

// 工具函数
const formatTime = (seconds) => {
  const mins = Math.floor(seconds / 60)
  const secs = seconds % 60
  return `${mins.toString().padStart(2, '0')}:${secs.toString().padStart(2, '0')}`
}

const formatDateTime = (date) => {
  return date.toLocaleString('zh-CN', {
    month: 'short',
    day: 'numeric',
    hour: '2-digit',
    minute: '2-digit'
  })
}

const getConfidenceColor = (confidence) => {
  if (confidence >= 0.9) return '#52c41a'
  if (confidence >= 0.7) return '#faad14'
  return '#ff4d4f'
}

// 生命周期
onMounted(() => {
  loadHistoryFromStorage()
  
  // 检查浏览器支持
  if (!canUseVoiceInput.value) {
    ElMessage.warning('您的浏览器不支持语音识别功能')
  }
})

onUnmounted(() => {
  // 清理资源
  if (recordingTimer) {
    clearInterval(recordingTimer)
  }
  
  if (mediaRecorder && mediaRecorder.state === 'recording') {
    mediaRecorder.stop()
  }
  
  if (audioContext) {
    audioContext.close()
  }
})

// 监听设置变化
watch([selectedLanguage, audioQuality], () => {
  // 设置变化时重新初始化音频
  if (mediaRecorder) {
    mediaRecorder = null
  }
})
</script>

<style scoped>
.voice-input-component {
  width: 100%;
  max-width: 600px;
  margin: 0 auto;
}

.voice-input-container {
  background: white;
  border-radius: 16px;
  padding: 30px;
  box-shadow: 0 4px 20px rgba(0, 0, 0, 0.1);
}

.recording-status {
  text-align: center;
  margin-bottom: 30px;
  transition: all 0.3s ease;
}

.recording-status.active {
  transform: scale(1.05);
}

.status-indicator {
  position: relative;
  display: inline-block;
  margin-bottom: 20px;
}

.pulse-ring {
  position: absolute;
  top: 50%;
  left: 50%;
  transform: translate(-50%, -50%);
  width: 120px;
  height: 120px;
  border: 3px solid #ff4d4f;
  border-radius: 50%;
  animation: pulse 2s infinite;
}

.status-icon {
  width: 80px;
  height: 80px;
  background: linear-gradient(135deg, #2c5aa0, #1890ff);
  border-radius: 50%;
  display: flex;
  align-items: center;
  justify-content: center;
  color: white;
  font-size: 32px;
  box-shadow: 0 4px 15px rgba(44, 90, 160, 0.3);
  transition: all 0.3s ease;
}

.recording-status.active .status-icon {
  background: linear-gradient(135deg, #ff4d4f, #ff7875);
  box-shadow: 0 4px 15px rgba(255, 77, 79, 0.3);
}

.recording-status.processing .status-icon {
  background: linear-gradient(135deg, #faad14, #ffc53d);
  box-shadow: 0 4px 15px rgba(250, 173, 20, 0.3);
}

.status-text h3 {
  color: #333;
  font-size: 18px;
  font-weight: 600;
  margin: 0 0 8px 0;
}

.status-text p {
  color: #666;
  font-size: 14px;
  margin: 0;
}

.recording-time {
  font-size: 16px;
  font-weight: 600;
  color: #ff4d4f;
}

.audio-visualizer {
  margin: 20px 0;
  text-align: center;
}

.visualizer-canvas {
  border: 1px solid #f0f0f0;
  border-radius: 8px;
  background: #fafafa;
}

.control-buttons {
  display: flex;
  justify-content: center;
  gap: 15px;
  margin: 30px 0;
  flex-wrap: wrap;
}

.record-btn {
  min-width: 140px;
  height: 50px;
  font-size: 16px;
  font-weight: 600;
}

.play-btn,
.clear-btn {
  min-width: 120px;
  height: 50px;
}

.recognition-result {
  background: #f8f9fa;
  border-radius: 12px;
  padding: 20px;
  margin: 20px 0;
}

.result-header {
  display: flex;
  align-items: center;
  justify-content: space-between;
  margin-bottom: 15px;
}

.result-header h4 {
  color: #2c5aa0;
  font-size: 16px;
  font-weight: 600;
  margin: 0;
  display: flex;
  align-items: center;
  gap: 8px;
}

.result-actions {
  display: flex;
  gap: 10px;
}

.result-content {
  min-height: 60px;
}

.processing-indicator {
  text-align: center;
}

.processing-text {
  color: #666;
  font-size: 14px;
  margin-top: 15px;
}

.recognition-text p {
  color: #333;
  font-size: 15px;
  line-height: 1.6;
  margin: 0 0 15px 0;
  padding: 15px;
  background: white;
  border-radius: 8px;
  border-left: 4px solid #2c5aa0;
}

.confidence-indicator {
  display: flex;
  align-items: center;
  gap: 10px;
}

.confidence-label {
  color: #666;
  font-size: 13px;
  white-space: nowrap;
}

.confidence-bar {
  flex: 1;
  max-width: 200px;
}

.error-message {
  text-align: center;
  color: #ff4d4f;
  padding: 20px;
}

.error-message i {
  font-size: 24px;
  margin-bottom: 10px;
}

.error-message p {
  margin: 10px 0;
}

.voice-settings {
  margin: 20px 0;
}

.settings-content {
  padding: 15px 0;
}

.setting-item {
  display: flex;
  align-items: center;
  gap: 15px;
  margin-bottom: 15px;
}

.setting-label {
  min-width: 80px;
  color: #333;
  font-size: 14px;
  font-weight: 500;
}

.unit-text {
  color: #666;
  font-size: 13px;
  margin-left: 5px;
}

.voice-history {
  margin-top: 30px;
  border-top: 1px solid #f0f0f0;
  padding-top: 20px;
}

.history-header {
  display: flex;
  align-items: center;
  justify-content: space-between;
  margin-bottom: 15px;
}

.history-header h4 {
  color: #2c5aa0;
  font-size: 16px;
  font-weight: 600;
  margin: 0;
  display: flex;
  align-items: center;
  gap: 8px;
}

.clear-history-btn {
  color: #ff4d4f;
}

.history-list {
  max-height: 300px;
  overflow-y: auto;
}

.history-item {
  display: flex;
  align-items: flex-start;
  justify-content: space-between;
  padding: 12px;
  background: white;
  border-radius: 8px;
  margin-bottom: 8px;
  border: 1px solid #f0f0f0;
  transition: all 0.2s ease;
}

.history-item:hover {
  border-color: #2c5aa0;
  box-shadow: 0 2px 8px rgba(44, 90, 160, 0.1);
}

.history-content {
  flex: 1;
  margin-right: 15px;
}

.history-text {
  color: #333;
  font-size: 14px;
  line-height: 1.4;
  margin-bottom: 5px;
}

.history-meta {
  display: flex;
  gap: 15px;
  color: #999;
  font-size: 12px;
}

.history-actions {
  display: flex;
  gap: 5px;
  flex-shrink: 0;
}

.history-actions .delete-btn {
  color: #ff4d4f;
}

@keyframes pulse {
  0% {
    transform: translate(-50%, -50%) scale(1);
    opacity: 1;
  }
  100% {
    transform: translate(-50%, -50%) scale(1.5);
    opacity: 0;
  }
}

/* 响应式设计 */
@media (max-width: 768px) {
  .voice-input-container {
    padding: 20px;
  }
  
  .control-buttons {
    flex-direction: column;
    align-items: center;
  }
  
  .record-btn,
  .play-btn,
  .clear-btn {
    width: 100%;
    max-width: 200px;
  }
  
  .setting-item {
    flex-direction: column;
    align-items: flex-start;
    gap: 8px;
  }
  
  .setting-label {
    min-width: auto;
  }
  
  .history-item {
    flex-direction: column;
    gap: 10px;
  }
  
  .history-actions {
    align-self: flex-end;
  }
}
</style>